"""
字节跳动豆包模型适配器
"""

import httpx
import json
import re
from typing import Dict, Any, List, Optional
import logging
from .base_adapter import BaseModelAdapter

logger = logging.getLogger(__name__)


class DoubaoAdapter(BaseModelAdapter):
    """字节跳动豆包模型适配器"""

    def __init__(self, api_key: str, api_url: str = "https://ark.cn-beijing.volces.com/api/v3/chat/completions", model: str = "doubao-pro-4k"):
        super().__init__(api_key, api_url, model)

    async def generate_completion(
        self,
        messages: List[Dict[str, str]],
        temperature: float = 0.2,
        max_tokens: int = 4000,
        timeout: float = 300.0,
        **kwargs
    ) -> str:
        """生成文本完成"""
        try:
            # 构建请求数据
            request_data = {
                "model": self.model,
                "messages": messages,
                "temperature": temperature,
                "max_tokens": max_tokens,
                "stream": False,
                **kwargs
            }

            # 尝试添加JSON格式要求，如果失败则移除
            try_json_format = True
            if try_json_format:
                request_data["response_format"] = {"type": "json_object"}

            async with httpx.AsyncClient(timeout=timeout) as client:
                response = await client.post(
                    self.api_url,
                    headers={
                        "Authorization": f"Bearer {self.api_key}",
                        "Content-Type": "application/json"
                    },
                    json=request_data
                )

                if response.status_code != 200:
                    error_detail = ""
                    try:
                        error_response = response.json()
                        error_detail = f", 错误详情: {error_response}"

                        # 检查是否是JSON格式不支持的错误
                        if "response_format" in str(error_response) and try_json_format:
                            logger.warning(
                                "豆包模型不支持JSON格式，尝试不使用response_format参数")
                            # 移除JSON格式要求重试
                            request_data.pop("response_format", None)
                            response = await client.post(
                                self.api_url,
                                headers={
                                    "Authorization": f"Bearer {self.api_key}",
                                    "Content-Type": "application/json"
                                },
                                json=request_data
                            )
                            if response.status_code == 200:
                                result = response.json()
                                if "choices" in result and result["choices"]:
                                    content = result["choices"][0]["message"]["content"]
                                    logger.info(
                                        f"豆包API调用成功（无JSON格式），返回内容长度: {len(content)}")
                                    return content
                    except:
                        error_detail = f", 响应内容: {response.text[:200]}"

                    raise Exception(
                        f"豆包API调用失败: 状态码={response.status_code}{error_detail}")

                result = response.json()

                # 豆包API返回格式检查
                if "choices" not in result or not result["choices"]:
                    raise Exception("豆包API返回格式异常：缺少choices字段")

                content = result["choices"][0]["message"]["content"]

                logger.info(f"豆包API调用成功，返回内容长度: {len(content)}")
                return content

        except Exception as e:
            logger.error(f"豆包API调用失败: {str(e)}")
            raise

    def get_provider_name(self) -> str:
        """获取提供商名称"""
        return "字节跳动豆包"

    def get_supported_models(self) -> List[str]:
        """获取支持的模型列表"""
        # 豆包适配器支持任意豆包模型名称
        # 返回常见的模型作为参考，但不限制使用其他豆包模型
        common_models = [
            # 标准豆包模型
            "doubao-pro-4k",
            "doubao-pro-32k",
            "doubao-pro-128k",
            "doubao-lite-4k",
            "doubao-lite-32k",
            # Doubao-Seed系列模型
            "doubao-seed-1.6",
            "doubao-seed-1.6-flash",
            "doubao-seed-1.6-thinking",
            "Doubao-Seed-1.6-flash",
            "Doubao-Seed-1.6-pro",
            "Doubao-Seed-1.6-lite",
            # 新版本豆包模型（2025年版本）
            "doubao-1-5-pro-32k-250115",
            "doubao-1-5-lite-32k-250115",
            "doubao-1-5-pro-4k-250115",
            "doubao-1-5-lite-4k-250115",
            "doubao-1-5-flash-32k-250115",
            # 2025年6月及以后的新模型格式
            "doubao-seed-1.6-flash-250615",
            "doubao-seed-1.7-flash",
            "doubao-seed-2.0-pro",
            "doubao-2-0-pro-32k",
            "doubao-2-0-lite-128k",
            # 其他可能的豆包模型格式
            "doubao-4k",
            "doubao-32k",
            "doubao-128k",
            "Doubao-pro-4k",
            "Doubao-pro-32k",
            "Doubao-lite-4k"
        ]

        # 如果当前模型不在常见列表中，也添加进去（支持未来模型）
        if self.model and self.model not in common_models:
            common_models.append(self.model)
            logger.info(f"添加未知豆包模型到支持列表: {self.model}")

        return common_models

    def validate_config(self) -> bool:
        """验证配置是否有效"""
        if not self.api_key or self.api_key.strip() == "":
            logger.error("豆包API密钥未配置")
            return False

        if not self.api_url or self.api_url.strip() == "":
            logger.error("豆包API地址未配置")
            return False

        if not self.model or self.model.strip() == "":
            logger.error("豆包模型名称未配置")
            return False

        # 检查是否为占位符
        placeholder_keys = ["your-doubao-api-key-here", "your-api-key-here"]
        if self.api_key in placeholder_keys:
            logger.error("检测到豆包API密钥为占位符，请配置真实的API密钥")
            return False

        # 检查模型名称是否为豆包相关模型（仅警告，不阻止使用）
        if not self._is_doubao_model(self.model):
            logger.info(f"使用自定义豆包模型名称: {self.model}")

        return True

    def _is_doubao_model(self, model_name: str) -> bool:
        """检查是否为豆包模型"""
        doubao_patterns = [
            "doubao-",      # 标准格式: doubao-pro-4k
            "Doubao-",      # 首字母大写: Doubao-Seed-1.6-flash
            "DOUBAO-",      # 全大写格式
        ]

        model_lower = model_name.lower()
        doubao_keywords = ["doubao", "豆包"]

        # 检查是否匹配任何豆包模式
        for pattern in doubao_patterns:
            if model_name.startswith(pattern):
                return True

        # 检查是否包含豆包关键词
        for keyword in doubao_keywords:
            if keyword in model_lower:
                return True

        # 特殊检查：新版本豆包模型格式 (如: doubao-1-5-pro-32k-250115)
        if re.match(r'doubao-\d+-\d+-(pro|lite|flash)-\d+k?-\d+', model_lower):
            return True

        return False
